import { ref } from "vue";
import { defineStore } from "pinia";
import { convertFileSrc, invoke } from "@tauri-apps/api/core";
import { Player } from "@/utils/player.js";

// 播放器状态
// pub struct AudioInfo {
//   pub path: String,         // 路径
//   pub title: String,        // 标题
//   pub artist: String,       // 艺术家
//   pub album: String,        // 专辑
//   pub genre: String,        // 流派
//   pub album_artist: String, // 专辑艺术家
//   pub duration: u64,        // 时长
//   pub bitrate: u32,         // 比特率
//   pub sample_rate: u32,     // 采样率
//   pub bit_depth: u8,        // 比特深度
//   pub channels: u8,         // 声道数
//   pub year: u32,            // 年份
//   pub track: u32,           // 轨道
//   pub comment: String,      // 注释
//   pub size: u64,            // 文件大小
//   pub lyric: String,        // 歌词
//   // pub cover: Vec<u8>, // 封面
//   pub cover: String, // 封面 base64 编码
//   pub dir: String,   // 文件夹名字
// }
// ============== 网络歌曲必有 ====================
//   is_online: bool,  // 是否为在线歌曲
//   method: String,   // 网络歌曲，GET/POST
//   headers: Map,     // 网络歌曲，附加头信息

// {
// path: '',
// title: '',
// artist: '',
// album: '',
// genre: '',
// album_artist: '',
// duration: 0,
// bitrate: 0,
// sample_rate: 0, 
// bit_depth: 0,
// channels: 1,
// year: 0,
// track: 0,
// comment: '',
// size: 0,
// lyric: '',
// cover: '',
// dir: '',

// is_online: false, 
// method: 'GET',
// headers: {}
// }

export const usePlayerStateStore = defineStore(
  "playerStore",
  () => {
    // 本地歌曲
    const localDirs = ref([]); // 本地文件夹信息
    const localMusics = ref([]); // 本地歌曲信息，包含 AudioInfo struct本身信息

    // 网络歌曲
    const netMusics = ref([]); // 网络歌曲信息，包含 AudioInfo struct本身和附加信息

    // favorite
    const favoriteMusics = ref([]); // 收藏歌曲信息

    // Player 当前播放列表
    const curPlayer = ref(null); // 播放器实例
    const curPlayList = ref([]); // 播放器使用的playlist，内容等同与netMusics
    const curPlayerPos = ref(0); // 当前播放歌曲的seek位置
    const curPlayerLoop = ref(false); // 单曲循环? 列表循环
    const curPlayerRate = ref(1.0); // 播放速度
    const curPlayerVolume = ref(100); // 音量 1-100
    const curPlayMusic = ref({
      path: "",
      title: "---------",
      artist: "--",
      album: "---------",
      genre: "---------",
      album_artist: "---------",
      duration: 0,
      bitrate: 0,
      sample_rate: 0,
      bit_depth: 0,
      channels: 0,
      year: 0,
      track: 0,
      comment: "---------",
      size: 0,
      lyric: '',
      cover: '',
      dir: '',
    }); // 当前播放歌曲信息

    // 用户自定义的播放列表
    const userPlayLists = ref([
      { name: "🎵 自己歌单", tag: "me-1", list: [] },
    ]);

    var percentage = computed(() => {
      if (!curPlayer.value) return 0;
      if (curPlayMusic.value.duration == 0) return 0;
      return (curPlayerPos.value * 100) / curPlayMusic.value.duration;
    });

    function isPlaying() {
      if (!curPlayer.value) return false;
      return curPlayer.value.instance().playing();
    }

    function secondsToMinutesSeconds(seconds) {
      var minutes = Math.floor(seconds / 60); // 计算分钟
      var secondsRemain = seconds % 60; // 计算剩余秒数
      return (
        minutes + ":" + (secondsRemain < 10 ? "0" + secondsRemain : secondsRemain)
      ); // 格式化输出
    }

    var duration_show = computed(() => {
      return secondsToMinutesSeconds(curPlayerPos.value) + "/" + secondsToMinutesSeconds(curPlayMusic.value.duration);
    });

    var localMusicDiskSize = computed(() => {
      var sz = 0;
      localMusics.value.forEach((inf) => {
        sz += inf.size;
      });
      return sz;
    });

    // 扫描本地文件夹，返回文件夹信息
    async function scanLocalDir() {
      let list_inf = [];
      for (let i = 0; i < localDirs.value.length; i++) {
        let dir = localDirs.value[i];
        let inf = await invoke("my_audio_scan", {
          path: dir,
          recursive: false,
        });
        console.log("scan", dir, inf);
        if (inf) list_inf = list_inf.concat(inf);
      }
      localMusics.value = list_inf;
    }

    // 修改某个本地歌曲信息
    // path: 歌曲本身的本地路径
    // info: AudioInfo struct 本身
    async function modifyLocalMusic(path, info) {
      await invoke("my_audio_modify", { path: path, info: info });
    }

    // 本地路径转换为url路径
    function localPath2Url(path) {
      return convertFileSrc(path);
    }

    // 播放歌曲，同时清理上一次的遗留播放器实例
    // inf: AudioInfo struct 本身
    function play_new(inf, cb_err, cb_end, cb_seek) {
      if (curPlayer.value) {
        curPlayer.value.destroy();
      }
      let url = '';
      if( inf.is_online ?? false ){
        url = inf.path;
      }else{
        url = localPath2Url(inf.path);
      }      
      let method = inf.method ?? "GET";
      let headers = inf.headers ?? "";
      curPlayer.value = new Player(
        url,
        (curPlayerVolume.value * 1.0) / 100,
        curPlayerRate.value,
        method,
        headers,
        cb_err,
        cb_end,
        cb_seek
      );
    }

    // 控制当前播放
    // play, pause, stop, seek, volume, rate
    function play_ctrl(cmd) {
      if (!curPlayer.value) return;

      switch (cmd) {
        case "play":
        case "resume":
        case "stop":
        case "pause":
          curPlayer.value.ctrl(cmd, 0);
          break;
        case "seek":
          curPlayer.value.ctrl(cmd, curPlayerPos.value);
          break;
        case "volume":
          curPlayer.value.ctrl(cmd, curPlayerVolume.value);
          break;
        case "rate":
          curPlayer.value.ctrl(cmd, curPlayerRate.value);
          break;
      }
    }

    // 获取next/prev歌曲信息
    // cmd: next/prev
    // return AudioInfo struct
    function get_next_prev(cmd) {
      let idx = curPlayList.value.findIndex(
        (item) => item.path == curPlayMusic.value.path
      );
      let next_idx = 0;
      switch (cmd) {
        case "next":
          next_idx = idx + 1;
          break;
        case "prev":
          next_idx = idx - 1;
          break;
      }
      if (next_idx < 0 || next_idx >= curPlayList.value.length) return null;
      return curPlayList.value[next_idx];
    }

    // 添加歌曲到播放列表
    function add_to_playlist(inf, is_online, method, headers) {
      let idx = curPlayList.value.findIndex((item) => item.path == inf.path);
      if (idx >= 0) return;

      var pl = {
        ...inf,
        is_online: is_online,
        method: method,
        headers: headers,
      };
      curPlayList.value.push(pl);
    }

    function add_to_favorite(inf, is_online, method, headers) {
      let idx = favoriteMusics.value.findIndex((item) => item.path == inf.path);
      if (idx >= 0) return;

      var pl = {
        ...inf,
        is_online: is_online,
        method: method,
        headers: headers,
      };
      favoriteMusics.value.push(pl);
    }
    /**
     * 从本地音乐列表中移除指定的音乐文件
     * @param {Object} inf - 包含音乐文件路径的对象
     * @returns {void} - 无返回值
     */
    function remove_from_local(inf) {
      var idx = localMusics.value.findIndex((item) => item.path == inf.path);
      if (idx < 0 || idx >= localMusics.value.length) return;
      localMusics.value.splice(idx, 1);
    }
    function remove_from_list(inf) {
      var idx = curPlayList.value.findIndex((item) => item.path == inf.path);
      if (idx < 0 || idx >= curPlayList.value.length) return;
      curPlayList.value.splice(idx, 1);
    }

    function $reset() {
      curPlayList.value = [];
      curPlayer.value = null;
      curPlayerPos.value = 0;
      curPlayerLoop.value = false;

      localDirs.value = [];
      localMusics.value = [];
      netMusics.value = [];
      favoriteMusics.value = [];
      userPlayLists.value = [];
    }

    return {
      localDirs,
      localMusics,
      netMusics,
      curPlayer,
      curPlayList,
      curPlayerPos,
      curPlayerLoop,
      curPlayerRate,
      curPlayerVolume,
      curPlayMusic,
      scanLocalDir,
      modifyLocalMusic,
      localPath2Url,
      play_new,
      play_ctrl,
      get_next_prev,
      add_to_playlist,
      percentage,
      isPlaying,
      duration_show,
      localMusicDiskSize,
      add_to_favorite,
      remove_from_local,
      favoriteMusics,
      userPlayLists,
      remove_from_list,
      $reset,
    };
  },
  {
    persist: true,
  }
);
